package com.evil.common.application.dto.process.node;

import com.evil.common.application.dto.permission.app.AppPermissionDTO;
import com.evil.common.application.dto.process.node.back.FallbackConfigDTO;
import com.evil.common.application.dto.process.node.btn.NodeButtonConfigDTO;
import com.evil.common.application.dto.process.node.gateway.GatewayConfigDTO;
import com.evil.common.application.dto.process.node.setting.NodeControlSettingDTO;
import com.evil.common.application.dto.process.node.submit.SubmitRefreshConfigDTO;
import com.evil.common.application.dto.robot.RobotConfigDTO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Range;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;

/**
 * 应用流程节点 实体
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class NodeInfoDTO extends NodeBaseDTO {

    /**
     * 复制属性时需要过滤字段
     */
    public static String[] IGNORE_PROPERTIES = new String[]{
            "gatewayConfig",
            "robotConfig",
            "submitRefreshConfig",
            "nodeFallbackConfig",
            "nodeButtonConfig"
    };

    /**
     * 是否开启重新触发数据关联或公式(0:否, 1:是)
     */
    @NotNull(message = "请选择是否开启重新触发数据关联或公式")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer recalculation;

    /**
     * 重新触发数据关联或公式的控件id集合
     */
    private List<Long> recalculationControlIds;

    /**
     * 网关配置(node_type为0时值有效)
     */
    @Valid
    private GatewayConfigDTO gatewayConfig;

    /**
     * 机器人配置(node_type为9时值有效，node_type为10时值有效)
     */
    @Valid
    private RobotConfigDTO robotConfig;

    /**
     * 编号是否可见(0:否, 1:是)
     */
    @NotNull(message = "编号是否可见参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer visibleSn;

    /**
     * 申请人是否可见(0:否, 1:是)
     */
    @NotNull(message = "申请人是否可见参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer visibleApplicant;

    /**
     * 申请时间是否可见(0:否, 1:是)
     */
    @NotNull(message = "申请时间是否可见参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer visibleApplyDate;

    /**
     * 更新时间是否可见(0:否, 1:是)
     */
    @NotNull(message = "更新时间是否可见参数不能为空")
    private Integer visibleUpdateDate;

    /**
     * 允许查看流程日志(0:否, 1:是)
     */
    @NotNull(message = "允许查看流程日志参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer processLog;

    /**
     * 处理反馈(0:否, 1:是)
     */
    @NotNull(message = "处理反馈参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer handleFeedback;

    /**
     * 流程超时处理(0:否, 1:是)
     */
    @NotNull(message = "流程超时处理参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer nodeOvertime;

    /**
     * 超时触发类型，0:自定义时间, 1:表单值
     */
    @NotNull(message = "超时触发类型参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer triggerType;

    /**
     * 超时触发表单控件id
     */
    private Long triggerField;

    /**
     * 超时条件
     */
    private Integer triggerCondition;

    /**
     * 超时条件单位，0:天, 1:时, 2:分
     */
    @NotNull(message = "超时条件单位参数不能为空")
    @Range(min = 0, max = 2, message = "参数错误")
    private Integer triggerConditionUnit;

    /**
     * 超时自动提交，0: 关闭, 1: 开启
     */
    @NotNull(message = "超时自动提交参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer autoSubmit;

    /**
     * 超时提醒，0: 关闭, 1: 开启
     */
    @NotNull(message = "超时提醒参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer overtimeRemind;

    /**
     * 节点超时提醒人列表
     */
    @Valid
    private List<AppPermissionDTO> overtimeReminds;

    /**
     * 超时提醒条件
     */
    private Integer remindCondition;

    /**
     * 超时提醒条件单位，0:天, 1:时, 2:分
     */
    @NotNull(message = "超时提醒条件单位参数不能为空")
    @Range(min = 0, max = 2, message = "参数错误")
    private Integer remindConditionUnit;

    /**
     * 关联报表(0:否, 1:是)
     */
    @NotNull(message = "关联报表参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer relevancyReporting;

    /**
     * 关联报表(0:可以查看全部关联报表, 1:限制关联报表可查看范围)
     */
    @NotNull(message = "关联报表参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer relevancyType;

    /**
     * 开启节点提交重新更新字段关联数据(0:否, 1:是)
     */
    @NotNull(message = "开启节点提交重新更新字段关联数据参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer submitRefresh;

    /**
     * 节点提交重新更新字段关联数据配置
     */
    @Valid
    private List<SubmitRefreshConfigDTO> submitRefreshConfig;

    /**
     * 待办转交(0:否, 1:是)
     */
    @NotNull(message = "待办转交参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer pendingDivert;

    /**
     * 待办转交类型(0:全部成员, 1:指定成员)
     */
    @NotNull(message = "待办转交参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer pendingDivertType;

    /**
     * 待办转交人列表
     */
    @Valid
    private List<AppPermissionDTO> pendingDiverts;

    /**
     * 节点撤回(0:否, 1:是)
     */
    @NotNull(message = "节点撤回参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer nodeBack;

    /**
     * 流程回退(0:否, 1:是)
     */
    @NotNull(message = "流程回退参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer nodeFallback;

    /**
     * 流程回退配置
     */
    @Valid
    private FallbackConfigDTO nodeFallbackConfig;

    /**
     * 流程拒绝(0:否, 1:是)
     */
    @NotNull(message = "流程拒绝参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer nodeRefuse;

    /**
     * 流程可发起留言(0:否, 1:是)
     */
    @NotNull(message = "流程可发起留言参数不能为空")
    @Range(min = 0, max = 1, message = "参数错误")
    private Integer nodeMessage;

    /**
     * 流程按钮配置
     */
    @Valid
    @NotNull(message = "流程按钮配置不能为空")
    private NodeButtonConfigDTO nodeButtonConfig;

    /**
     * 节点处理人列表
     */
    @Valid
    private List<AppPermissionDTO> handlers;

    /**
     * 节点控件配置列表
     */
    @Valid
    private List<NodeControlSettingDTO> nodeControlSettings;

    public NodeInfoDTO() {
        // 默认值
        this.gatewayConfig = new GatewayConfigDTO();
        this.recalculationControlIds = new ArrayList<>();
        this.robotConfig = new RobotConfigDTO();
        this.overtimeReminds = new ArrayList<>();
        this.submitRefreshConfig = new ArrayList<>();
        this.pendingDiverts = new ArrayList<>();
        this.nodeFallbackConfig = new FallbackConfigDTO();
        this.nodeButtonConfig = new NodeButtonConfigDTO();
        this.handlers = new ArrayList<>();
        this.nodeControlSettings = new ArrayList<>();
    }
}
